#include <stdio.h>
#include <string.h>

#include "xlx_wakeup_save.h"
#include "xlx_configfile.h"
#include "xlx_core.h"
#include "xlx_platform.h"

wake_data_t g_curret_wakeup_src = {0};    // 本次唤醒源数据
wakeup_record_t g_sys_wakeup_src = {0};   // 系统开机原因

/*
* 增加一条唤醒记录
* 更新后记录+1
* 如果大于LAST_WAKEUP_RECORD_MAX，会从前面覆盖
*/
void wakup_src_add(wakeup_record_t *rec, wake_data_t *dat){
    TutuTime t;

    TUTULOG("wakup_src_add_timestamp: %ld", dat->datetime);

    if(dat->datetime<DATETIME_MIN){
        return;
    }
    xlx_localtime(dat->datetime, &t);

    TUTULOG("all_cnt=%d, cnt=%d, last=%d(before)", 
        g_sys_wakeup_src.total, g_sys_wakeup_src.last_count, g_sys_wakeup_src.last_id
    );

    TUTULOG("apReset=%d, cpReset=%d, wakeup=%d, stamp=%ld, ver:%d, checksum=%s",
        dat->ap_reset_state, dat->cp_reset_state, dat->wakeup_source,
        dat->datetime, dat->ap_version, 
        dat->ap_checksum 
    );
    
    memcpy(&rec->wakeup_list[rec->last_id], dat, sizeof(wake_data_t));

    TUTULOG("id_%d: ap=%d, cp=%d, wakeup=%d, ver:%d, checksum=%s, tmStamp=%ld(%d-%d-%d %d:%d:%d) saving",
        rec->last_id, g_sys_wakeup_src.wakeup_list[rec->last_id].ap_reset_state, g_sys_wakeup_src.wakeup_list[rec->last_id].cp_reset_state, 
        g_sys_wakeup_src.wakeup_list[rec->last_id].wakeup_source,
        g_sys_wakeup_src.wakeup_list[rec->last_id].ap_version, g_sys_wakeup_src.wakeup_list[rec->last_id].ap_checksum ,
        rec->wakeup_list[rec->last_id].datetime,
        t.year, t.mon, t.day, t.hour, t.min, t.sec
    );

    rec->total++;
    if(rec->last_count < LAST_WAKEUP_RECORD_MAX){
        rec->last_count++;
    }

    rec->last_id++;
    if(rec->last_id >= LAST_WAKEUP_RECORD_MAX){
        rec->last_id = 0;
    }

    TUTULOG("all_cnt=%d, cnt=%d, last=%d(after)", 
        g_sys_wakeup_src.total, g_sys_wakeup_src.last_count, g_sys_wakeup_src.last_id
    );
}

/*
* 保存唤醒源数据到文件
*/
void tutu_save_wakeup_src_cfg(){
    unsigned int the_last_timestamp_id;
    if((0 == g_sys_wakeup_src.last_id) || (g_sys_wakeup_src.last_id >= LAST_WAKEUP_RECORD_MAX)){
        the_last_timestamp_id = LAST_WAKEUP_RECORD_MAX -1;
    }
    else {
        the_last_timestamp_id = g_sys_wakeup_src.last_id -1;
    }
    g_tutufile.write_file(TUTU_WAKEUP_SRC_FILE_NAME,(char*)&g_sys_wakeup_src,sizeof(wakeup_record_t));

    TUTULOG("all_cnt=%d, cnt=%d, last=%d(valid=%d), timestamp=%ld",g_sys_wakeup_src.total,g_sys_wakeup_src.last_count,
        g_sys_wakeup_src.last_id, the_last_timestamp_id, g_sys_wakeup_src.wakeup_list[the_last_timestamp_id].datetime);

    TUTULOG("WakeupSrc saved");
}

/*
* 加载唤醒源数据到文件
*/
void tutu_load_wakeup_src_cfg(){
    const char * file = TUTU_WAKEUP_SRC_FILE_NAME;
    unsigned long int len = sizeof(wakeup_record_t);
    if(g_tutufile.get_file_size(file) == len){
        g_tutufile.read_file(file,(char*)&g_sys_wakeup_src,&len);
    }else{
        memset(&g_sys_wakeup_src,0,len);
    }
    TUTULOG("WakeupSrc loaded");
}

/*
* 因为开机的时候，时间不对，后面要更新时间
* 保存到NVRAM
*/
void update_last_datetime_and_save(wakeup_record_t *rec, unsigned long dtime){
    unsigned int last_id;
    // TUTULOG("tm=%ld(id=%d)",rec->wakeup_list[rec->last_id].datetime, rec->last_id);
    last_id = rec->last_id;
    if(rec->last_id == 0){
        last_id = LAST_WAKEUP_RECORD_MAX;
    }
    else {
        last_id --;
    }
    rec->wakeup_list[last_id].datetime = dtime;
    //TUTULOG("tm=%ld(id=%d)",rec->wakeup_list[last_id].datetime, last_id);
    tutu_save_wakeup_src_cfg();
}

/*
* 串口打印日志
* last_count: 最后唤醒开机的记录数
*/
void show_all_wakeup_src(unsigned int start_id, unsigned int rec_count){
    unsigned int i;
    unsigned int list_id;
    TutuTime t; 
    unsigned long beijing_timestamp;

    TUTULOG("all_cnt=%d, cnt=%d, last=%d", 
        g_sys_wakeup_src.total, g_sys_wakeup_src.last_count, g_sys_wakeup_src.last_id
    );

    for ( i = start_id; ((i < g_sys_wakeup_src.last_count) && (i < (rec_count+start_id))); i++)
    {
        list_id = (g_sys_wakeup_src.last_id - i + LAST_WAKEUP_RECORD_MAX -1)%LAST_WAKEUP_RECORD_MAX;
        beijing_timestamp = g_sys_wakeup_src.wakeup_list[list_id].datetime+28800;  // 东八区 +28800
        xlx_localtime(beijing_timestamp, &t);     
        TUTULOG("id_%d(list_%d): apReset=%d, cpReset=%d, wakup=%d(1=RTC,2=Shake,5=Keyd,6=charge) ,ver:%d, checksum=%s, timestamp=%ld(%d-%02d-%02d %02d:%02d:%02d)",
            i, list_id, g_sys_wakeup_src.wakeup_list[list_id].ap_reset_state, g_sys_wakeup_src.wakeup_list[list_id].cp_reset_state, 
            g_sys_wakeup_src.wakeup_list[list_id].wakeup_source,
            g_sys_wakeup_src.wakeup_list[list_id].ap_version, g_sys_wakeup_src.wakeup_list[list_id].ap_checksum ,
            beijing_timestamp, t.year, t.mon, t.day, t.hour, t.min, t.sec
        );
    }    
}

/*
* 串口打印日志
* start_id: 开始记录编号（最后唤醒开机的记录数）
* rec_count: 多少条记录
* ret_buff:  返回的数据
*/
void get_all_wakeup_src_data(unsigned int start_id, unsigned int rec_count, char * ret_buff){
    unsigned int i;
    unsigned int list_id;
    TutuTime t; 
    unsigned long beijing_timestamp;
    char tmp_buff[129] = {0};
    char all_buff[1024] ={0};
    
    TUTULOG("all_cnt=%d, cnt=%d, last=%d", 
        g_sys_wakeup_src.total, g_sys_wakeup_src.last_count, g_sys_wakeup_src.last_id
    );

    for ( i = start_id; ((i < g_sys_wakeup_src.last_count) && (i < (rec_count+start_id))); i++)
    {
        list_id = (g_sys_wakeup_src.last_id - i + LAST_WAKEUP_RECORD_MAX -1)%LAST_WAKEUP_RECORD_MAX;
        beijing_timestamp = g_sys_wakeup_src.wakeup_list[list_id].datetime+28800;  // 东八区 +28800
        xlx_localtime(beijing_timestamp, &t);   
        // id:ap,cp,src,ver,checksum,timer
        TUTUSprintf(tmp_buff, "%d:ap=%d,cp=%d,src=%d,%d,%s(%d%02d%02d%02d%02d%02d);", // 16+38  --> 54
            i, g_sys_wakeup_src.wakeup_list[list_id].ap_reset_state, g_sys_wakeup_src.wakeup_list[list_id].cp_reset_state, 
            g_sys_wakeup_src.wakeup_list[list_id].wakeup_source,
            g_sys_wakeup_src.wakeup_list[list_id].ap_version, g_sys_wakeup_src.wakeup_list[list_id].ap_checksum ,
            t.year, t.mon, t.day, t.hour, t.min, t.sec
        );
        strcat(all_buff, tmp_buff);
        TUTULOG("%s(all_len=%d)", tmp_buff,strlen(all_buff));
        if(strlen(all_buff)>896){
            break;
        }
    } 

    TUTULOG("%s(all_len=%d)", tmp_buff,strlen(all_buff));
    memcpy(ret_buff, all_buff, strlen(all_buff));
}

/*
* 按顺序显示全部数据
*/
void show_queue_wakeup_src(void){
    unsigned int i;
    unsigned long beijing_timestamp;

    for ( i = 0; i < LAST_WAKEUP_RECORD_MAX; i++)
    {
        beijing_timestamp = g_sys_wakeup_src.wakeup_list[i].datetime+28800;
        TUTULOG("id_%d: apReset=%d, cpReset=%d, Wakeup=%d, ver:%d, checksum=%s,timestamp=%ld",
            i, g_sys_wakeup_src.wakeup_list[i].ap_reset_state, g_sys_wakeup_src.wakeup_list[i].cp_reset_state, 
            g_sys_wakeup_src.wakeup_list[i].wakeup_source,
            g_sys_wakeup_src.wakeup_list[i].ap_version, g_sys_wakeup_src.wakeup_list[i].ap_checksum,
            beijing_timestamp
        );
    }
    
}

/*
* 清除所有唤醒源数据
*/
void clear_all_wakeup_data(void)
{
    memset(&g_sys_wakeup_src, 0, sizeof(g_sys_wakeup_src));
    TUTULOG("all wakeup data cleaned.");
    tutu_save_wakeup_src_cfg();
}